﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.CodeDom;
using System.IO;

using EdgeStatz.ESSystems.Objects;
using EdgeStatz.ModelEngine.FormTools;

namespace EdgeStatz.DesignTools
{
    public partial class AutoGen : UserControl
    {
        public delegate void FormGenerated();

        public event FormGenerated FormGeneratedEvent;

        private string sysfolder;
        public AutoGen()
        {
            InitializeComponent();
            RefreshTable();

            sysfolder = GlobalSystemSettings.SystemFolderPath;
        }
        #region Forms
        private void RefreshTable()
        {
            FolderDefinition[] folders = Designer.FolderEngine.GetFolderDefinitions();
            FormDefinition[] forms = Designer.FormEngine.FormDefinitions;

            foreach (FolderDefinition foldef in folders)
            {
                //if (foldef.Level != FolderLevel.Four)
                //{
                    bool exists = false;
                    foreach (FormDefinition formdef in forms)
                    {
                        if (foldef.Name.ToLower() == formdef.Folder.ToLower())
                        {
                            exists = true;
                            break;
                        }
                    }
                    dgvForms.Rows.Add(new object[] { false, exists, foldef.Name , foldef.TableName});
                //}
            }
        }

        private void bForm_Generate_Click(object sender, EventArgs e)
        {
            progressBar1.Value = 0;
            dgvForms.EndEdit();
            bool[] overwrite = new bool[] {false, false};
            foreach (DataGridViewRow dr in dgvForms.Rows)
            {
                if ((bool)dr.Cells[0].Value)
                {

                    if (!overwrite[0] && (bool)dr.Cells[1].Value)
                    {
                        switch (MessageBox.Show("A form already exists for the folder " +
                        (string)dr.Cells[2].Value + "\nAre you sure you want replace the existing form?", "Overwirte File",
                        MessageBoxButtons.YesNoCancel, MessageBoxIcon.Stop))
                        {
                            case DialogResult.Yes:
                                Designer.FormEngine.ReplaceFormDefinitionByFolderName(
                                    GenerateForm((string)dr.Cells[2].Value), (string)dr.Cells[2].Value);
                                break;
                            case DialogResult.No:
                                break;
                            case DialogResult.Cancel:
                                return;
                        }
                    }
                    else
                    {
                        Designer.FormEngine.AddFormDefinition(GenerateForm((string)dr.Cells[2].Value));
                    }
                }
                progressBar1.Value += 100 / dgvForms.Rows.Count;
            }
            Designer.FormEngine.SaveModelFile();
            progressBar1.Value = 100;
            FormGeneratedEvent.Invoke();
        }

        private FormDefinition GenerateForm(string foldername) 
        {
            FolderDefinition folderdef = Designer.FolderEngine.GetFolderDefinitionByName(foldername);
            if (folderdef.Level == FolderLevel.Four)
                return GenerateFormTab(folderdef);

            TableDefinition tabledef = Designer.DatabaseEngine.GetTableByName(folderdef.TableName);
            string classname = foldername.Replace(" ", "_");
            FormGenerator generator = new FormGenerator(classname, folderdef, tabledef);

            int i = 0;
            int idcol = -1;
            foreach (ColumnDefinition coldef in tabledef.ColumnArray)
            {
                if (coldef.Type == ColumnType.GUID && coldef.PrimaryKey && coldef.ForeignKey == null)
                {
                    idcol = i;
                    //generator.AddIDColumn(coldef.Name, "guid");
                    i++;
                    continue;
                }
                generator.AddComponent_Label(coldef.Name);
                switch (coldef.Type)// Add design members
                {
                    case ColumnType.GUID:
                        if (coldef.ForeignKey != null)
                        {
                            generator.AddComponent_ComboBox(coldef.Name, i);
                            string display = "";
                            string value = "";
                            FolderDefinition fdef = Designer.FolderEngine.GetFolderDefinitionByTable(coldef.ForeignKey.Table);
                            if (fdef != null)
                            {
                                if (coldef.ForeignKey.Column == fdef.ValueExp)
                                {
                                    display = fdef.DisplayExp;
                                    value = fdef.ValueExp;
                                }
                                else
                                    throw new Exception();
                            }
                            else
                            {
                                EnumFolderDefinition efdef = Designer.FolderEngine.GetEnumDefinitionByTable(coldef.ForeignKey.Table);
                                if (efdef != null)
                                {
                                    if (coldef.ForeignKey.Column == efdef.ValueExp)
                                    {
                                        display = efdef.DisplayExp;
                                        value = efdef.ValueExp;
                                    }
                                    else
                                        throw new Exception();
                                }
                                else
                                    throw new Exception("Folder not found for table: " + tabledef.Name);
                            }
                            generator.AddDefaultValues(coldef.Name, coldef.ForeignKey.Table, display, value);
                        }
                        break;
                    case ColumnType.Int:
                        generator.AddComponent_NumericUpDown(coldef.Name, 0, i);
                        break; 
                    case ColumnType.Float:
                        generator.AddComponent_NumericUpDown(coldef.Name, 2, i);
                        break;
                    case ColumnType.Bit:
                        generator.AddComponent_CheckBox(coldef.Name, coldef.DefaultValue == "1" ? true : false, i);
                        break; 
                    case ColumnType.Datetime:
                        generator.AddComponent_DateTimePicker(coldef.Name, i);
                        break;
                    case ColumnType.Varchar:
                        generator.AddComponent_TextBox(coldef.Name, coldef.Length, i);
                        break;
                }
                i++;
            }
            foreach (SubFolderDefinition subfdef in folderdef.SubFolders)
            {
                FolderDefinition subfolder = Designer.FolderEngine.GetFolderDefinitionByName(subfdef.Name);
                if (subfolder.Level == FolderLevel.Four)
                {
                    generator.AddTab(subfolder.Name, subfolder.TableName, subfdef.Column, idcol);
                }
            }

            // Add programming logic

            return generator.WriteSourceCode(); 
        }

        private FormDefinition GenerateFormTab(FolderDefinition folderdef)
        {
            if (folderdef.Level != FolderLevel.Four)
                throw new Exception("Cannot generate tabs for folders that are not level four.");

            TableDefinition tabledef = Designer.DatabaseEngine.GetTableByName(folderdef.TableName);
            string classname = folderdef.Name.Replace(" ", "_");
            TabGenerator generator = new TabGenerator(classname, folderdef.Name);

            foreach (ColumnDefinition coldef in tabledef.ColumnArray)
            {
                switch (coldef.Type)// Add design members
                {
                    case ColumnType.GUID:
                        if (coldef.PrimaryKey)
                        {
                            generator.AddColumn_Id(coldef.Name);
                            break;
                        }
                        if (coldef.ForeignKey != null)
                        {
                            generator.AddColumn_Combobox(coldef.Name);
                            string display = "";
                            string value = "";
                            FolderDefinition fdef = Designer.FolderEngine.GetFolderDefinitionByTable(coldef.ForeignKey.Table);
                            if (fdef != null)
                            {
                                if (coldef.ForeignKey.Column == fdef.ValueExp)
                                {
                                    display = fdef.DisplayExp;
                                    value = fdef.ValueExp;
                                }
                                else
                                    throw new Exception();
                            }
                            else
                            {
                                EnumFolderDefinition efdef = Designer.FolderEngine.GetEnumDefinitionByTable(coldef.ForeignKey.Table);
                                if (efdef != null)
                                {
                                    if (coldef.ForeignKey.Column == efdef.ValueExp)
                                    {
                                        display = efdef.DisplayExp;
                                        value = efdef.ValueExp;
                                    }
                                    else
                                        throw new Exception();
                                }
                                else
                                    throw new Exception("Folder not found for table: " + tabledef.Name);
                            }
                            generator.AddDefaultValues(coldef.Name, coldef.ForeignKey.Table, display, value);
                        }
                        break;
                    case ColumnType.Int:
                        generator.AddColumn_TextBox(coldef.Name);
                        break;
                    case ColumnType.Float:
                        generator.AddColumn_TextBox(coldef.Name);
                        break;
                    case ColumnType.Bit:
                        generator.AddColumn_CheckBox(coldef.Name);
                        break;
                    case ColumnType.Datetime:
                        generator.AddColumn_TextBox(coldef.Name);
                        break;
                    case ColumnType.Varchar:
                        generator.AddColumn_TextBox(coldef.Name);
                        break;
                }
            }
            // Add programming logic
            return generator.WriteSourceCode(); 
        }
        #endregion

        private void b_SelectAll_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < dgvForms.RowCount; i++)
                dgvForms.Rows[i].Cells[0].Value = true;
            dgvForms.EndEdit();
        }

        private void b_SelectNone_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < dgvForms.RowCount; i++)
                dgvForms.Rows[i].Cells[0].Value = false;
            dgvForms.EndEdit();
        }
    }
}
